home *** CD-ROM | disk | FTP | other *** search
- (*----------------------------------------------------------------------*)
- (* Find_Line --- Find line on file F *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Find_Line( n : REAL );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Find_Line *)
- (* *)
- (* Purpose: Finds and moves to specified line on file F *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Find_Line( n: REAL ); *)
- (* *)
- (* n --- line to be found *)
- (* *)
- (* Calls: Read_Line *)
- (* RMIN *)
- (* Clear_Buffer *)
- (* Skip_To_Line *)
- (* Reset_F *)
- (* Scan_To_Eof *)
- (* *)
- (* Remarks: *)
- (* *)
- (* On exit eod=TRUE if the line does not exist. In this case the *)
- (* buffer is full and it contains the lines at end of the file. *)
- (* Otherwise eod=FALSE, line n is in the buffer, and top points *)
- (* to it. *)
- (* *)
- (* The algorithm divides into three cases. *)
- (* *)
- (* Case 1. The line preceeds the buffer. In this case the file *)
- (* is reset and the buffer is cleared. The goal is to exit *)
- (* with the buffer full and with line n at the end of the buffer. *)
- (* This is accomplished by skipping the proper number of lines, *)
- (* then reading lines into the buffer until line n has been *)
- (* reached. *)
- (* *)
- (* Case 2. The line is inside the buffer. A simple linear search *)
- (* of the buffer locates the requested line. *)
- (* *)
- (* Case 3. The line follows the buffer. This is the complicated *)
- (* case. As in case 1, the goal is to exit with a full buffer *)
- (* and with line n at the end of the buffer. However, if line n *)
- (* does not exist then we want to exit with a full buffer *)
- (* consisting of the lines at the end of the file. For efficiency *)
- (* in large forward skips, we don't want to simply read lines into *)
- (* the buffer until line n or eof is encountered. Skipping is *)
- (* faster than reading, so we'd prefer to skip lines, then read a *)
- (* full buffer's worth. The problem is to determine how many *)
- (* lines to skip. *)
- (* *)
- (* (a) If line n is within Max_buf_lines of the last line in the *)
- (* buffer then no lines are skipped. Lines are simply read *)
- (* into the buffer until line n or eof is reached. This is *)
- (* a "short" forwards skip. *)
- (* *)
- (* (b) Assume (a) doesn't hold. If n is less than or equal to the *)
- (* maximum line number seen so far then we know that line n *)
- (* must exist. In this case we skip to line (n-Max_buf_lines),*)
- (* then read lines into the buffer until line n is reached. *)
- (* *)
- (* (c) Assume neither (a) nor (b) holds. If we have earlier *)
- (* encountered eof on file f, then Max_line is the largest *)
- (* line number on the file, and we know whether or not line *)
- (* n exists. In this case we skip to line min(n,Max_line) - *)
- (* Max_buf_lines, and then read lines into the buffer until *)
- (* either line n or eof is reached. *)
- (* *)
- (* (d) If none of cases (a), (b) or (c) hold then we scan to *)
- (* eof to determine whether or not line n exists. Max_line *)
- (* is now the largest line number on the file. File f is *)
- (* reset, and we proceed as in case (c). Note that this case *)
- (* can occur at most once per run of PibList. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- m: REAL;
-
- BEGIN (* Find_Line *)
-
- eod := FALSE;
- (* Case 1 *)
- IF n < First^.lnum THEN
- BEGIN
-
- Reset_F;
-
- Clear_Buffer;
-
- IF n > Max_buf_lines THEN Skip_To_Line( n - Max_buf_lines );
-
- REPEAT
- Read_Line;
- UNTIL last^.lnum = n;
-
- top := last
-
- END (* Case 2 *)
- ELSE IF n <= last^.lnum THEN
- BEGIN
-
- top := first;
-
- WHILE ( Top^.lnum < n ) DO top := Top^.next
-
- END
- ELSE
- BEGIN (* Case 3 *)
-
- IF ( NOT eof_seen ) AND ( ( n - Max_buf_lines ) > last^.lnum )
- AND (n > Max_line) THEN
- Scan_To_Eof;
-
- m := RMIN( n , Max_line ) - Max_buf_lines;
-
- IF m > last^.lnum THEN
- BEGIN
- Clear_Buffer;
- Skip_To_Line( m )
- END;
-
- REPEAT
- Read_Line;
- UNTIL ( last^.lnum = n ) OR EOF( F );
-
- top := last;
- eod := Top^.lnum < n;
-
- END;
-
- END (* Find_Line *);
-
- (*----------------------------------------------------------------------*)
- (* Find_Page --- Find first line of page on F *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Find_Page( n : REAL );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Find_Page *)
- (* *)
- (* Purpose: Locates first line of page on file F. *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Find_Page( n: REAL ); *)
- (* *)
- (* n --- Page to be found *)
- (* *)
- (* Calls: Read_Line *)
- (* Skip_To_Page *)
- (* Scan_To_Eof *)
- (* Clear_Buffer *)
- (* Reset_F *)
- (* *)
- (* Remarks: *)
- (* *)
- (* On exit eod=TRUE if the page does not exist, in which case *)
- (* the buffer is full and it contains the Lines at the end of *)
- (* the file. *)
- (* *)
- (* Otherwise eod=FALSE, the first Line of page n is in the buffer, *)
- (* and top points to it. *)
- (* *)
- (* The algorithm used by find_page is almost identical to that used *)
- (* by find_line. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- before: BOOLEAN;
- m: REAL;
-
- BEGIN (* Find_Page *)
-
- eod := FALSE;
-
- before := ( n < First^.pnum ) OR
- ( ( n = First^.pnum ) AND ( First^.Txt[1] <> eject_char ) );
-
- IF before THEN
- BEGIN
-
- Reset_F;
-
- Clear_Buffer;
-
- IF n > Max_buf_pages THEN Skip_To_Page ( n - Max_buf_pages );
-
- REPEAT
- Read_Line;
- UNTIL last^.pnum = n;
-
- top := last
-
- END
- ELSE IF n <= last^.pnum THEN
- BEGIN
-
- top := first;
-
- WHILE ( Top^.pnum < n ) DO top := Top^.next
-
- END
- ELSE
- BEGIN
-
- IF ( NOT eof_seen ) AND ( ( n - Max_buf_pages ) > last^.pnum )
- AND ( n > Max_page ) THEN
- Scan_To_Eof;
-
- m := RMIN( n , Max_page ) - Max_buf_pages;
-
- IF m > last^.pnum THEN
- BEGIN
- Clear_Buffer;
- Skip_To_Page( m )
- END;
-
- REPEAT
- Read_Line;
- UNTIL ( last^.pnum = n ) OR EOF( F );
-
- top := last;
- eod := Top^.pnum < n;
-
- END;
-
- END (* Find_Page *);
-
- (*----------------------------------------------------------------------*)
- (* Find_String --- Find next occurrence of string on F *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Find_String( S: AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Find_String *)
- (* *)
- (* Purpose: Find next occurrence of string on F *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Find_String( S: AnyStr ); *)
- (* *)
- (* S --- String to be found *)
- (* *)
- (* Calls: Read_Line *)
- (* Find_Line *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Found: BOOLEAN;
- Done: BOOLEAN;
- LineNo: INTEGER;
- n: INTEGER;
-
- LABEL 1;
-
- BEGIN (* Find_String *)
-
- Found := FALSE;
- Done := FALSE;
-
- Search_Lpos := 0;
- Search_Col := 0;
-
- REPEAT
-
- bot := top;
- LineNo := 0;
- n := Height;
-
- WHILE ( n > 0 ) AND ( NOT Eod ) DO
- BEGIN
-
- LineNo := LineNo + 1;
-
- Search_Col := POS( Search_Str , Bot^.Txt );
-
- IF Search_Col <> 0 THEN
- BEGIN
- Search_Lpos := LineNo;
- Search_Line := Bot^.Lnum;
- Found := TRUE;
- GOTO 1;
- END;
-
- n := n - 1;
-
- IF n > 0 THEN
- IF bot = last THEN
- BEGIN
- Read_Line;
- Eod := eof(f);
- bot := last;
- END
- ELSE
- bot := Bot^.next;
-
- END;
-
- Done := ( n > 0 );
-
- IF ( NOT Done ) THEN
- Find_Line( Top^.lnum + Height );
-
- 1:
- UNTIL ( Found OR Done );
-
- END (* Find_String *);